﻿
namespace Sai.Core.Rules
{
    using System.Linq;
    using Sai.Core.Introspection;

    public class CheckObsoleteEvents : IReferenceTypeRule
    {
        public void Validate(ReferenceTypeDeclaration was, ReferenceTypeDeclaration isNow, ITypeDifference typeDifference)
        {
            var obsolete = isNow.Events.FindObsoleteMembers();

            foreach (var obs in obsolete)
            {
                typeDifference.IdentifiedChange(
                    new UnaryTypeChange(
                        TypeChangeReason.EventObsolete,
                        obs
                    ));
            }
        }
    }

    public class CheckTypeEvents : IClassRule
    {
        public void Validate(ClassDeclaration was, ClassDeclaration isNow, ITypeDifference typeDifference)
        {
            if (was.Events.Count == 0 && isNow.Events.Count == 0)
            {
                return;
            }

            var removed = isNow.Events.FindRemovedMembers(was.Events);

            foreach (var remove in removed)
            {
                typeDifference.IdentifiedChange(
                    new UnaryTypeChange(
                        TypeChangeReason.EventRemoved,
                        remove
                    ));
            }

            var added = isNow.Events.FindAddedMembers(was.Events);

            foreach (var add in added)
            {
                typeDifference.IdentifiedChange(
                    new UnaryTypeChange(
                        TypeChangeReason.EventAdded,
                        add
                    ));
            }

            var commonEvents = isNow.Events.FindMatchingMembers(was.Events);

            if (commonEvents.Any())
            {
                foreach (var ev in commonEvents)
                {
                    EventDeclaration oldEvent = ev.Item1;
                    EventDeclaration newEvent = ev.Item2;

                    if (oldEvent != null && newEvent != null)
                    {
                        if (oldEvent.TypeName != newEvent.TypeName)
                        {
                            typeDifference.IdentifiedChange(
                                new BinaryTypeChange(
                                    TypeChangeReason.EventChanged,
                                    oldEvent,
                                    newEvent,
                                    string.Format(
                                        "Event changed type from {0} to {1}",
                                        oldEvent.TypeName,
                                        newEvent.TypeName
                                        )
                                ));
                        }
                    }
                }
            }
        }
    }
}
